#ifndef PRINCIPAL_CPP_
#define PRINCIPAL_CPP_

// TODO remover
#include <QDebug>

#include "principal.h"

JanelaPrincipal :: JanelaPrincipal() : ui( NULL ), 
                                       bluechips( NULL ), 
                                       smallcaps( NULL ),
                                       banco( NULL )
{
    ui = new Ui_JanelaPrincipal;

    ui->setupUi( this );

    if ( !carregar_bd() )
    {
        if ( !criar_bd() )
        {
            exibir_mensagem( this, "Erro", "Não foi possível criar/acessar "
                                           "as informações do banco de dados. ",
                                           Critica );

            // Deletando o arquivo caso este tenha sido criado com erro
            QFile bd( "fundamentalis.db3" );

            if ( bd.exists() )
            {
                bd.remove();
            }

            exit( 0 );
        }
    }

    // Carregando as informações dos papéis a partir do banco de dados
    carregar_bluechips();
    carregar_smallcaps();

    // Preenchendo a árvore com os papéis carregados
    preencher_papeis();

    // Carregando as configurações da carteira do usuário a partir do banco de
    // dados
    carregar_carteira();

    // Conectando o sinal de finalização do carregamento das consultas web ao
    // devido slot
    connect( pagina.mainFrame(), SIGNAL( loadFinished( bool ) ),
             this, SLOT( carregamento_finalizado( bool ) ) );
}


JanelaPrincipal :: ~JanelaPrincipal()
{
    // Fechando o banco de dados
    banco->close();

    // Deletando objetos alocados
    if ( ui != NULL )
    {
        delete ui;
    }

    if ( bluechips != NULL )
    {
        delete bluechips;
    }

    if ( smallcaps != NULL )
    {
        delete smallcaps;
    }

    if ( banco != NULL )
    {
        delete banco;
    }
}


bool JanelaPrincipal :: carregar_bd()
{
   QFile *arquivo = new QFile( "fundamentalis.db3" );

    if ( arquivo->exists() )
    {
        banco = new QSqlDatabase();
        
        *banco = QSqlDatabase::addDatabase( "QSQLITE" );

        banco->setDatabaseName( "fundamentalis.db3" );

        if ( banco->open() )
        {
            return true;
        }
    }

    return false;
}


bool JanelaPrincipal :: carregar_bluechips()
{
    // TODO
    /*
    bluechips = new QList< QStringList >;

    QFile arq( "bluechips.dat" );

    if ( !arq.open( QIODevice::ReadOnly | QIODevice::Text ) )
    {
        return false;
    }

    QTextStream stream( &arq );

    stream.setCodec( "UTF-8" );

    QString linha = stream.readLine();

    QStringList valores;

    // Se a primeira linha for comentário (#) deverá ser ignorada
    if ( linha.at( 0 ) == '#' )
    {
        linha = stream.readLine();
    }

    // Enquanto houverem linhas...
    while ( !linha.isNull() && linha.size() != 0 )
    {
        // Quebrando a linha a partir do separador " - "
        valores = linha.split( QRegExp( " - " ) );

        // Se a linha não tiver dois valores, o formato do arquivo está errado
        if ( valores.size() != 2 )
        {
            return false;
        }

        // Adicionando na lista das bluechips
        bluechips->append( valores );

        linha = stream.readLine();
    }

    // TODO ordenar?

    return true;
    */
}


bool JanelaPrincipal :: carregar_smallcaps()
{
    // TODO
    /*
    smallcaps = new QList< QStringList >;

    QFile arq( "smallcaps.dat" );

    if ( !arq.open( QIODevice::ReadOnly | QIODevice::Text ) )
    {
        return false;
    }

    QTextStream stream( &arq );

    stream.setCodec( "UTF-8" );

    QString linha = stream.readLine();

    QStringList valores;

    // Se a primeira linha for comentário (#) deverá ser ignorada
    if ( linha.at( 0 ) == '#' )
    {
        linha = stream.readLine();
    }

    // Enquanto houverem linhas...
    while ( !linha.isNull() && linha.size() != 0 )
    {
        // Quebrando a linha a partir do separador " - "
        valores = linha.split( QRegExp( " - " ) );

        // Se a linha não tiver dois valores, o formato do arquivo está errado
        if ( valores.size() != 2 )
        {
            return false;
        }

        // Adicionando na lista das bluechips
        smallcaps->append( valores );

        linha = stream.readLine();
    }

    // TODO ordenar?

    return true;
    */
}


bool JanelaPrincipal :: criar_bd()
{
    // Alocando o objeto do banco
    banco = new QSqlDatabase();
    
    *banco = QSqlDatabase::addDatabase( "QSQLITE" );

    banco->setDatabaseName( "fundamentalis.db3" );

    if ( !banco->open() )
    {
        return false;
    }

    // Criando a query que executará os comandos SQL
    QSqlQuery query( *banco );

    // Abrindo o arquivo que contém a query a ser executada
    QFile script_tabelas( ":/sql/tabelas.sql" );

    if ( !script_tabelas.open( QIODevice::ReadOnly | QIODevice::Text ) )
    {
        return false;
    }

    // Lendo e quebrando o arquivo por comandos, uma vez que não é possível
    // executar mais de um comando de uma só vez na query
    QString conteudo = script_tabelas.readAll();

    QStringList comandos = conteudo.split( QRegExp( ";\n" ) );

    // O último caractere de cada comando é também um ';', o que faz com que a
    // lista tenha um elemento a mais
    comandos.removeLast();

    // Executando os comandos
    for ( int i = 0 ; i < comandos.size() ; i++ )
    {
        if ( !query.exec( comandos[i] ) )
        {
            return false;
        }
    }

    return true;
}


QStringList JanelaPrincipal :: processar_dados( const QString &dados )
{
    QStringList resultado;

    //TODO
    dados.at( 2 );
    
    return resultado;
}


void JanelaPrincipal :: carregar_carteira()
{
    // TODO
}


void JanelaPrincipal :: preencher_papeis()
{
    // TODO
    /*
    QTreeWidgetItemIterator it( ui->papeis );

    while ( *it )
    {
        // Inserindo os papéis contidos no arquivo "smallcaps.dat"
        if ( (*it)->text( 0 ) == "Small-Caps" )
        {
            for ( int i = 0 ; i < smallcaps->size() ; i++ )
            {
                // Criando um novo filho
                QTreeWidgetItem *filho = new QTreeWidgetItem( (*smallcaps)[i] );

                // Adicionando o filho à árvore
                (*it)->addChild( filho );
            }
        }

        // Inserindo os papéis contidos no arquivo "bluechips.dat"
        if ( (*it)->text( 0 ) == "Blue-Chips" )
        {
            for ( int i = 0 ; i < bluechips->size() ; i++ )
            {
                // Criando um novo filho
                QTreeWidgetItem *filho = new QTreeWidgetItem( (*bluechips)[i] );

                // Adicionando o filho à árvore
                (*it)->addChild( filho );
            }
        }

        ++it;
    }*/
}


void JanelaPrincipal :: carregamento_finalizado( bool ok )
{
    if ( ok )
    {
        loop.exit();
    }
    else
    {
        // TODO
//        exibir_mensagem( "Não foi possível " );
    }
}


void JanelaPrincipal :: on_botao_analisar_clicked()
{
    // TODO Consultar banco para saber se ja nao existe nenhuma tupla com a data
    // atual para insercao das informacoes

    // Lista que contém todos os papeis carregados
    QList< QStringList > papeis = *smallcaps + *bluechips;

    // Atualizando número de passos da barra de progresso
    ui->barra_progresso->setRange( 0, papeis.size() );
    ui->barra_progresso->setEnabled( true );

    // Base da URL a ser consultada
    QString url_base( "http://www.fundamentus.com.br/detalhes.php?papel=" );

    QUrl url;

    QString papel, dados;

    QStringList dados_processados;

    for ( int i = 0 ; i < papeis.size() ; i++ )
    {
        // Código do papel
        papel = papeis.at( i )[0];

        // URL de consulta
        url.setUrl( url_base + papel );

        // Realizando a requisição na web
        pagina.mainFrame()->load( url );

        // Aguardando até o final do carregamento da página
        loop.exec();
        
        // Capturando as informações
        dados = pagina.mainFrame()->toPlainText();
           
        // Processando as informações extraídas da consulta
        dados_processados = processar_dados( dados );

        // Preenchendo a tabela correta no banco
        // Small-Caps
        if ( i + 1 <= smallcaps->size() )
        {
            // TODO preenchimento da tabela do banco
            // TODO Atualização das abas da interface
        }
        // Blue-Chips
        else
        {
            // TODO preenchimento da tabela do banco
            // TODO Atualização das abas da interface
        }
        
        // Atualizando a % da barra de progresso
        ui->barra_progresso->setValue( i + 1 );
    }

    // Reinicializando a barra de progresso
    ui->barra_progresso->reset();
    ui->barra_progresso->setEnabled( false );
}

#endif
